package com.gin.kotlin.gf2gamecommunity.routes

import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.Badge
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import androidx.navigation.toRoute
import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.collectAsLazyPagingItems
import com.gin.kotlin.enums.MessageType
import com.gin.kotlin.gf2gamecommunity.R
import com.gin.kotlin.gf2gamecommunity.app.App
import com.gin.kotlin.gf2gamecommunity.base.composable.MyImage
import com.gin.kotlin.gf2gamecommunity.base.composable.TabInfo
import com.gin.kotlin.gf2gamecommunity.base.composable.TabRowPager
import com.gin.kotlin.gf2gamecommunity.navi.GF2Navigator
import com.gin.kotlin.gf2gamecommunity.viewmodel.MessageViewModel
import com.gin.kotlin.response.message.Message
import com.gin.retrofit.utils.JacksonUtils
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable


fun NavGraphBuilder.messageList(messageViewModel: MessageViewModel, navigator: GF2Navigator) = composable<MessageListRoute>(
    // 从屏幕右侧进入，持续500毫秒
    enterTransition = { slideInHorizontally(tween(500)) { it } },
    // 从屏幕右侧退出，持续500毫秒
    exitTransition = { slideOutHorizontally(tween(500)) { it } },
) {
    MessageListComposable(route = it.toRoute(), messageViewModel = messageViewModel, navigator = navigator)
}

/**
 * 默认选择的消息类型（建议选择未读数最大的）
 * @constructor
 */
@Serializable
data class MessageListRoute(val id: Int = 1)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun MessageListComposable(route: MessageListRoute, messageViewModel: MessageViewModel = viewModel(), navigator: GF2Navigator) {
    var currentType by remember { mutableStateOf(MessageType.COMMENT) }
    var currentPagingData by remember { mutableStateOf( messageViewModel.messageList.fetch(currentType)) }
    val lazyPagingItems = currentPagingData.collectAsLazyPagingItems()
    val unreadCountState = messageViewModel.unreadCount.fetch().observeAsState()
    val coroutineScope = rememberCoroutineScope()
    navigator.apply {
        Scaffold(
            topBar = {
                TopAppBar(navigationIcon = {
                    IconButton(onClick = { onPopBackStack() }) {
                        Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "后退")
                    }
                }, actions = {
                    IconButton(onClick = {
                        val ids = lazyPagingItems.itemSnapshotList.filter { it?.isRead != true }.mapNotNull { it?.id }
                        if (ids.isNotEmpty()) {
                            App.toast("正在请求全部已读, 请等待刷新")
                            coroutineScope.launch {
                                messageViewModel.readAll(currentType, ids)
                                lazyPagingItems.refresh()
                                messageViewModel.unreadCount.fetch(true)
                            }
                        } else {
                            App.toast("当前没有未读消息")
                        }
                    }) {
                        Icon(painterResource(R.drawable.ic_eye_24), contentDescription = "全部已读")
                    }
                    IconButton(onClick = { lazyPagingItems.refresh() }) {
                        Icon(imageVector = Icons.Filled.Refresh, contentDescription = "刷新")
                    }
                }, title = {
                    Text("提醒消息")
                })
            },

            ) { paddingValues ->
            val modifier = Modifier.padding(paddingValues)
            Box(modifier = modifier.fillMaxSize()) {
                unreadCountState.value?.apply {
                    val unreadCountList = listOf(commentUnreadNum, likeUnreadNum, followUnreadNum, noticeUnreadNum)
                    val initialPage = unreadCountList.indexOfFirst { it > 0 }.coerceAtLeast(0)
                    val tabState = rememberPagerState(initialPage = initialPage, pageCount = { MessageType.entries.size })

                    LaunchedEffect(tabState) { snapshotFlow { tabState.currentPage }.collect { page ->
                        val type = MessageType.entries.first { it.ordinal == page }
                        currentType = type
                        currentPagingData = messageViewModel.messageList.fetch(type)
                    } }


                    TabRowPager(tabList = MessageType.entries.mapIndexed { index, type ->
                        val unread = unreadCountList[index]
                        val title = if (unread == 0) type.des else "${type.des} (${unread})"
                        TabInfo(title) {
                            MessageTypePage(
                                lazyPagingItems = lazyPagingItems,
                                onNavigateToUserCenter = { onNavigateToUserCenter(it) },
                                onNavigateToCommentSingle = { onNavigateToCommentSingle(it) },
                                onNavigateToCommentList = { onNavigateToCommentList(it) },
                                onRead = { messageViewModel.read(it, type) }
                            )
                        }
                    }, tabState = tabState, fillHeight = true)
                }
            }
        }
    }
}

@Composable
private fun MessageTypePage(
    lazyPagingItems: LazyPagingItems<Message>,
    onNavigateToUserCenter: (UserCenterRoute) -> Unit,
    onNavigateToCommentSingle: (CommentSingleRoute) -> Unit,
    onNavigateToCommentList: (CommentListRoute) -> Unit,
    onRead: (id: Int) -> Unit,
    modifier: Modifier = Modifier,
) {
    LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp), modifier = modifier
        .fillMaxWidth()
        .padding(8.dp)) {
        items(lazyPagingItems.itemCount) { page ->
            lazyPagingItems[page]?.apply {
                Box(contentAlignment = Alignment.TopEnd) {
                    if (!isRead) Badge(modifier = Modifier.size(12.dp))
                    Row(modifier = Modifier.clickable {
                        if (userId != null) {
                            onNavigateToUserCenter(UserCenterRoute(userId!!))
                        } else if (commentId != null && topicId != null) {
                            if (commentId!! > 0)
                                onNavigateToCommentSingle(CommentSingleRoute(topicId = topicId!!, commentId = commentId!!))
                            else {
                                onNavigateToCommentList(CommentListRoute(topicId!!))
                            }
                        }
                        if (!isRead) {
                            isRead = true
                            onRead(id)
                        }
                    }) {
                        MyImage(avatarUrl, modifier = Modifier
                            .clip(CircleShape)
                            .size(80.dp))
                        Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                            Text(title)
                            content?.let { Text(it, maxLines = 2, modifier = Modifier.graphicsLayer { alpha = 0.7f }) }
                            Text(logTime, textAlign = TextAlign.End, modifier = Modifier
                                .fillMaxWidth()
                                .graphicsLayer { alpha = 0.7f })
                        }
                    }
                }

            }
        }
    }
}